home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Reference / the cmsp digests ('94-'97) / csmp digest Vol 3 No 108 < prev    next >
Text File  |  1995-08-25  |  78KB  |  1,867 lines

  1. C.S.M.P. Digest             Thu, 24 Aug 95       Volume 3 : Issue 108
  2.  
  3. Today's Topics:
  4.  
  5.         Asynchronous File I-O
  6.         Saving and restoring current drawing port - necessary?
  7.         Where are my command line arguments?
  8.  
  9.  
  10.  
  11. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  12. (pottier@clipper.ens.fr).
  13.  
  14. The digest is a collection of article threads from the internet newsgroups
  15. comp.sys.mac.programmer.help, csmp.tools and csmp.misc. It is designed for
  16. people who read news semi-regularly and want an archive of the discussions.
  17. If you don't know what a newsgroup is, you probably don't have access to
  18. it. Ask your systems administrator(s) for details. If you don't have access
  19. to news, you may still be able to post messages to the group by using a
  20. mail server like anon.penet.fi (mail help@anon.penet.fi for more
  21. information).
  22.  
  23. Each issue of the digest contains one or more sets of articles (called
  24. threads), with each set corresponding to a 'discussion' of a particular
  25. subject.  The articles are not edited; all articles included in this digest
  26. are in their original posted form (as received by our news server at
  27. nef.ens.fr).  Article threads are not added to the digest until the last
  28. article added to the thread is at least two weeks old (this is to ensure that
  29. the thread is dead before adding it to the digest).  Article threads that
  30. consist of only one message are generally not included in the digest.
  31.  
  32. The digest is officially distributed by two means, by email and ftp.
  33.  
  34. If you want to receive the digest by mail, send email to listserv@ens.fr
  35. with no subject and one of the following commands as body:
  36.     help                                Sends you a summary of commands
  37.     subscribe csmp-digest Your Name     Adds you to the mailing list
  38.     signoff csmp-digest                 Removes you from the list
  39. Once you have subscribed, you will automatically receive each new
  40. issue as it is created.
  41.  
  42. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  43. Questions related to the ftp site should be directed to
  44. scott.silver@dartmouth.edu.
  45.  
  46. -------------------------------------------------------
  47.  
  48. >From domarkmk@aol.com (Domark MK)
  49. Subject: Asynchronous File I-O
  50. Date: 27 Jul 1995 23:54:02 -0400
  51. Organization: America Online, Inc. (1-800-827-6364)
  52.  
  53. After many hours of wasted time today, I've learned that asynchronous file
  54. I/O isn't possible on the Mac, at least until Apple rewrites the SCSI
  55. Manager.  I've heard that SCSI Manager 4.3 fixes that "for some machines",
  56. but I have it installed and it's not having any effect, and I need it to
  57. work for all machines (well, all PowerPC machines, including the upgrade
  58. cards).  I came across some code that makes async file calls from Time
  59. Manager completion routines, and tried that, but of course everything
  60. still stops as soon as the read is initiated and doesn't continue until
  61. it's finished.  I also found the async I/O Thread Manager code, but I
  62. haven't tried it because I believe it will behave the same as the Time
  63. Manager 'asynchronous' I/O.
  64.  
  65. All I want is to be able to read from a CD, while continuously drawing
  66. stuff on the screen.  (I'm playing an animation from the disk, using a
  67. double-buffering technique that relies on asynchronous reads.)  Is it
  68. possible?  Can it be done?  Does anyone have a sledgehammer I can borrow?
  69.  
  70. Thanks,
  71.  
  72. Mike.
  73.  
  74. ________________________________________________________________________
  75. Michael A. Kelly                                Senior Software Engineer
  76. mkelly@domark.com                                  Domark Software, Inc.
  77. ________________________________________________________________________
  78.  
  79. +++++++++++++++++++++++++++
  80.  
  81. >From jumplong@aol.com (Jump Long)
  82. Date: 29 Jul 1995 02:25:59 -0400
  83. Organization: America Online, Inc. (1-800-827-6364)
  84.  
  85. In article <3v9n0q$gfr@newsbf02.news.aol.com> Domark MK, domarkmk@aol.com
  86. writes:
  87.  
  88. >After many hours of wasted time today, I've learned that
  89. >asynchronous file I/O isn't possible on the Mac, at least until
  90. >Apple rewrites the SCSI Manager.  I've heard that SCSI Manager
  91. >4.3 fixes that "for some machines", but I have it installed and
  92. >it's not having any effect, and I need it to work for all
  93. >machines (well, all PowerPC machines, including the upgrade
  94. >cards).
  95.  
  96. The File Manager handles asynchronous requests now (and always has).
  97. However, there are certain limitations that make asynchronous File Manager
  98. requests only semi-useful.
  99.  
  100. The first limitation is the Macintosh file system (and much of the rest of
  101. the operating system) is currently single-threaded.  That means that you
  102. can have a dozen asynchronous requests outstanding but they execute one at
  103. a time.  The asynchronous requests that are waiting are kept in an OS
  104. queue and are handled (except in the special cases of retries and to
  105. remote AppleShare volumes) first in / first out.
  106.  
  107. The next limitation is that many device drivers and the SCSI Manager
  108. before SCSI Manager 4.3 handle all requests synchronously.  So, even
  109. though the File Manager calls the device driver asynchronously (because
  110. the File Manager request was made asynchronously), the device driver or
  111. SCSI Manager doesn't return control to the file system until the call is
  112. complete.
  113.  
  114. I guess a short overview of how the file system works might help here. 
  115. I'll use a Read as an example of what happens.  I'm going to leave out
  116. lots of the minor details, but you should get the general idea...
  117.  
  118. When you make a Read request to the File Manager, it looks at the trap
  119. word and sets a flag for itself if the async bit is set. Then it continues
  120. the handling of the Read; it makes sure the file is open with read access,
  121. calculates the offset where the Read should begin, and calls the routine
  122. that figures out where the file blocks to be read are on the disk.
  123.  
  124. Now, the File Manager is ready to read the data from the disk, so it needs
  125. to call the disk driver that owns the volume to read 1 or more blocks. 
  126. The File Manager checks the "async" flag and if the File Manager request
  127. was asynchronous, then it calls the disk driver asynchronously (with a
  128. completion routine) to read the blocks; if the request was synchronous,
  129. then it calls the disk driver synchronously.
  130.  
  131. If the call was made asynchronously, then when the File Manager gets
  132. control back, it returns control to the code that made the original File
  133. Manager request. Meanwhile, the disk driver reads the disk.  When the disk
  134. driver finishes and calls the completion routine, the File Manager has
  135. control again and continues handling the Read request.  (If more disk I/O
  136. is needed, it is made asynchronously again.)  When the File Manager has
  137. fulfilled the Read request, it sets the result code in the parameter
  138. block, it calls the completion routine for the asynchronous File Manager
  139. request (if there was one), and then checks to see if it needs to start
  140. handling another queued request.  If not, control is returned to whatever
  141. was interrupted.
  142.  
  143. As you can see, if the disk driver handles asynchronous requests to it
  144. synchronously, then the program that called the File Manager
  145. asynchronously never gets any time back before the call is complete. 
  146. Also, since the File Manager is single-threaded, a synchronous driver
  147. blocks all queued calls behind it.
  148.  
  149. So, what works now?  The AppleShare foreign file system has always handled
  150. almost all calls asynchronously so your program can get control back while
  151. your request is handled by an AppleShare file server. With SCSI Manager
  152. 4.3 and the proper asynchronous SCSI disk drivers on on all 040 and
  153. PowerPC based systems.
  154.  
  155. So, why are asynchronous calls still useful, even when the disk driver is
  156. synchronous?  Because you can make asynchronous requests at interrupt time
  157. without causing the file system to deadlock (if the file system is
  158. handling a call and you interrupt it and make a synchronous file system
  159. call, the file system can't finish what it's doing and can't give you
  160. control back... that's deadlock).
  161.  
  162. I hope that kind of clears things up for you. When we get a multi-threaded
  163. operating system on the Macintosh, things will be even better. You might
  164. want to read the "develop" magazine article I wrote for issue #13 if you
  165. can find it. It covers asynchronous programming techniques in detail.
  166.  
  167. - Jim Luther
  168.  
  169. +++++++++++++++++++++++++++
  170.  
  171. >From domarkmk@aol.com (Domark MK)
  172. Date: 29 Jul 1995 17:13:05 -0400
  173. Organization: America Online, Inc. (1-800-827-6364)
  174.  
  175. >>
  176. SCSI Manager 4.3
  177. provides asynchronous disk i/o, ASSUMING your driver supports asynchronous
  178. disk i/o.
  179. <<
  180.  
  181. OK, so when will I be able to assume that most everyone with a PowerMac
  182. has drivers for their cd-roms that support asynchronous i/o?  Is the
  183. driver in the hardware or is it in the Apple CD-ROM extensions (or their
  184. third-party substitutes)?  Is there a new version of the Apple CD-ROM
  185. extensions that support async i/o?  If so, could I include it with my
  186. software so that I could then assume they have a driver that supports
  187. async i/o?
  188.  
  189. Or do I just have to reduce the quality of my animation because of the
  190. limitations of prior versions of the system software?  (As I see it, async
  191. support would be standard in current drivers if the Mac OS had supported
  192. it sooner.)
  193.  
  194. Mike.
  195.  
  196. ________________________________________________________________________
  197. Michael A. Kelly                                Senior Software Engineer
  198. mkelly@domark.com                                  Domark Software, Inc.
  199. ________________________________________________________________________
  200.  
  201. +++++++++++++++++++++++++++
  202.  
  203. >From blob@apple.com (Brian Bechtel)
  204. Date: Sat, 29 Jul 1995 21:55:36 -0700
  205. Organization: Apple Computer, Inc.
  206.  
  207. In article <3ve891$mjh@newsbf02.news.aol.com>, domarkmk@aol.com (Domark
  208. MK) wrote:
  209. > OK, so when will I be able to assume that most everyone with a PowerMac
  210. > has drivers for their cd-roms that support asynchronous i/o?  
  211.  
  212. I'm not sure anyone can answer this question...
  213.  
  214. >Is the driver in the hardware 
  215.  
  216. No.  The driver is the software which understands how to talk to the hardware.
  217.  
  218. >or is it in the Apple CD-ROM extensions (or their third-party substitutes)?  
  219.  
  220. For the Apple CD-ROM software, the driver is called "Apple CD-ROM". 
  221. Apple's driver only supports Apple CD-ROM drives; you have to use third
  222. party drivers for third party drives.  Look at 
  223.   http://www.info.apple.com/dev/devinfo/maccdromfaq.html#thirdparty
  224. for some third party drivers.
  225.  
  226. >Is there a new version of the Apple CD-ROM extensions that support 
  227. >async i/o?  
  228.  
  229. I'm not sure what versions didn't support asynchronous i/o, if any.
  230.  
  231. >If so, could I include it with my software so that I could then 
  232. > assume they have a driver that supports async i/o?
  233.  
  234. If you want to redistribute Apple software, you have to contact Apple's
  235. software licensing department at sw.license@applelink.apple.com.  You'll
  236. have to contact the authors of third party software to find their
  237. redistribution requirements.
  238.  
  239. -- 
  240. --Brian Bechtel    blob@apple.com    Village Idiot, DTS
  241.  
  242. +++++++++++++++++++++++++++
  243.  
  244. >From domarkmk@aol.com (Domark MK)
  245. Date: 1 Aug 1995 12:35:43 -0400
  246. Organization: America Online, Inc. (1-800-827-6364)
  247.  
  248. >>Is there a new version of the Apple CD-ROM extensions that support 
  249. >>async i/o?  
  250. >
  251. >I'm not sure what versions didn't support asynchronous i/o, if any.
  252.  
  253. Hmmm, so if I have SCSI Manager 4.3.1, and Apple CD-ROM 5.0.1, and an
  254. Apple CD300, PBReadAsync should work asynchronously?  It doesn't.... 
  255. Could it be that the hardware doesn't support async i/o?
  256.  
  257. Mike.
  258. ________________________________________________________________________
  259. Michael A. Kelly                                Senior Software Engineer
  260. mkelly@domark.com                                  Domark Software, Inc.
  261. ________________________________________________________________________
  262.  
  263. +++++++++++++++++++++++++++
  264.  
  265. >From domarkmk@aol.com (Domark MK)
  266. Date: 1 Aug 1995 12:35:43 -0400
  267. Organization: America Online, Inc. (1-800-827-6364)
  268.  
  269. >>Is there a new version of the Apple CD-ROM extensions that support 
  270. >>async i/o?  
  271. >
  272. >I'm not sure what versions didn't support asynchronous i/o, if any.
  273.  
  274. Hmmm, so if I have SCSI Manager 4.3.1, and Apple CD-ROM 5.0.1, and an
  275. Apple CD300, PBReadAsync should work asynchronously?  It doesn't.... 
  276. Could it be that the hardware doesn't support async i/o?
  277.  
  278. Mike.
  279. ________________________________________________________________________
  280. Michael A. Kelly                                Senior Software Engineer
  281. mkelly@domark.com                                  Domark Software, Inc.
  282. ________________________________________________________________________
  283.  
  284. ---------------------------
  285.  
  286. >From duncant@sushi.mitre.or.jp (Duncan Thomson)
  287. Subject: Saving and restoring current drawing port - necessary?
  288. Date: Thu, 20 Jul 1995 09:31:12 +0530
  289. Organization: Nothing to do with my organization
  290.  
  291. Hi, Mac programming novice here with a question...
  292.  
  293. The "Inside Mac" books say that, before setting the current port (when you
  294. want to draw in it), you should save the previous port, then, after you
  295. are done drawing, set it back to what it was.   (Written in a confusing
  296. manner, I admit, but I think you know what I'm talking about.)
  297.  
  298. My question: Is this really necessary?  If all code sets the port as
  299. necessary before drawing in it, why bother to restore it?  Is there some
  300. problem with asynchronous processing going on here?
  301.  
  302. Thanks
  303. Duncan
  304.  
  305. p.s. Please e-mail me your response, as well as posting (if you think it's
  306. worth posting at all) as my news server is unreliable, and I may miss your
  307. answer if you just post.
  308.  
  309. +++++++++++++++++++++++++++
  310.  
  311. >From peter@adi.co.nz (Peter Bromley)
  312. Date: Fri, 21 Jul 1995 17:41:26 +1200
  313. Organization: ADInstruments
  314.  
  315. In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
  316. (Sean Crist) wrote:
  317.  
  318. > In article <duncant-2007950931120001@a09.dial.twics.com>,
  319. > Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
  320. > >Hi, Mac programming novice here with a question...
  321. > >
  322. > >The "Inside Mac" books say that, before setting the current port (when you
  323. > >want to draw in it), you should save the previous port, then, after you
  324. > >are done drawing, set it back to what it was.   (Written in a confusing
  325. > >manner, I admit, but I think you know what I'm talking about.)
  326. > >
  327. > >My question: Is this really necessary?  If all code sets the port as
  328. > >necessary before drawing in it, why bother to restore it?  Is there some
  329. > >problem with asynchronous processing going on here?
  330. > Well, I almost never do this, myself, and I've never had any problems.  My
  331. > personal programming policy is that it's every routine for itself as far as
  332. > the port is concerned; if a routine is expecting the port to be
  333. > such-and-such, it's that routine's responsibility to set it itself.  This
  334. > saves me from having to trace back through a dozen routines to see who
  335. > changed the port.
  336.  
  337. As if its all that difficult to do the right thing. All you need to do is
  338. use the GetPort, SetPort, code, SetPort combination as a response to the
  339. following things
  340.  
  341. Events
  342.      (update, activate, mousedown, keydown, appleevent),
  343. Internal program "events"
  344.      (idle, checkmouseshape, checknextWNEsleep, somedatachanged, dosomething)
  345.  
  346. If you do this right you need never set the port elsewhere (except to work
  347. with offscreen bitmaps / printing / ... well, maybe some other times)  :-)
  348.  
  349. > I _might_ make an exception (i.e. and save and restore the port) if I had
  350. > some routine which did drawing in a certain port and was frequently called
  351. > from within other routines which needed the port to be something in
  352. > particular, so that calling this drawing routine would be transparent.  But
  353. > in practice I find that I never need to do this.
  354.  
  355. See, if you did it _right_, you wouldnt ever need to protect individual
  356. routines ever.
  357.  
  358.  
  359. BTW: If IM says do something, you'ld have to be a fool or an expert to do
  360. otherwise (IMO of course).
  361.  
  362. -- 
  363. Peter Bromley                                  (peter@adi.co.nz)
  364. ADInstruments, Dunedin, New Zealand            
  365.  
  366. +++++++++++++++++++++++++++
  367.  
  368. >From pandhphot@aol.com (PandH Phot)
  369. Date: 20 Jul 1995 20:16:40 -0400
  370. Organization: America Online, Inc. (1-800-827-6364)
  371.  
  372. You'll find that often the current port is the monitor's "world". If you
  373. don't restore it and somebody tries to write to the monitor, bad things
  374. might happen. If you're always using modal dialogs you might get away with
  375. it, since they rule the world while they live and die oblivious to their
  376. neighbors, but I'm not even sure I'd count on that in the brave new
  377. permanent-Multifinder society we live in.
  378.  
  379. Besides, it's so easy, why fight it?
  380.  
  381. Paul
  382.  
  383. +++++++++++++++++++++++++++
  384.  
  385. >From kurisuto@babel.ling.upenn.edu (Sean Crist)
  386. Date: 21 Jul 1995 12:10:43 GMT
  387. Organization: University of Pennsylvania, Linguistics Department
  388.  
  389. In article <peter-2107951741260001@adi008.adi.co.nz>,
  390. Peter Bromley <peter@adi.co.nz> wrote:
  391. >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
  392. >(Sean Crist) wrote:
  393.  
  394. >> Well, I almost never do this, myself, and I've never had any problems.  My
  395. >> personal programming policy is that it's every routine for itself as far as
  396. >> the port is concerned; if a routine is expecting the port to be
  397. >> such-and-such, it's that routine's responsibility to set it itself.  This
  398. >> saves me from having to trace back through a dozen routines to see who
  399. >> changed the port.
  400. >
  401. >As if its all that difficult to do the right thing. All you need to do is
  402. >use the GetPort, SetPort, code, SetPort combination as a response to the
  403. >following things
  404.  
  405. *shrug*  I wasn't aware that this was an issue on which there is a "right"
  406. way to do things.  Your way works, but I don't see what's wrong with my
  407. way, as it works too, and doesn't violate any of Apple's rules (I think
  408. they included GetPort so that you _can_ preserve the port, not because you
  409. _have_ to).
  410.  
  411. Really, I think it's personal preference, and the important thing is that
  412. you pick a scheme and then _be consistant_ with it.  Since none of my
  413. routines make assumptions about what the port should be (with a very few
  414. exceptions which I always document clearly in my comments), none of them
  415. need to preserve it either, and I never run into trouble.
  416.  
  417. >> I _might_ make an exception (i.e. and save and restore the port) if I had
  418. >> some routine which did drawing in a certain port and was frequently called
  419. >> from within other routines which needed the port to be something in
  420. >> particular, so that calling this drawing routine would be transparent.  But
  421. >> in practice I find that I never need to do this.
  422. >
  423. >See, if you did it _right_, you wouldnt ever need to protect individual
  424. >routines ever.
  425. >
  426. >BTW: If IM says do something, you'ld have to be a fool or an expert to do
  427. >otherwise (IMO of course).
  428.  
  429. I agree that IM should be rigorously followed.  But I don't agree that I'm
  430. outside IM's rules here.  I'd be quite shocked to learn that IM somewhere
  431. says "If your routines change the port internally, they must always
  432. remember and restore the current port, and if you don't do this, your
  433. application is likely to break under future system releases."  The
  434. important point is that the port be correctly set at times when it matters,
  435. and there's more than one overall scheme for ensuring that this is so.
  436.  
  437.  
  438.   \/ __ __    _\_     --Sean Crist  (kurisuto@unagi.cis.upenn.edu)
  439.  ---  |  |    \ /     
  440.   _| ,| ,|   -----    For a free copy of the Bill of Rights, finger
  441.   _| ,| ,|    [_]     this account.
  442.    |  |  |    [_]     
  443.  
  444.  
  445.  
  446. +++++++++++++++++++++++++++
  447.  
  448. >From kurisuto@babel.ling.upenn.edu (Sean Crist)
  449. Date: 21 Jul 1995 00:36:45 GMT
  450. Organization: University of Pennsylvania, Linguistics Department
  451.  
  452. In article <duncant-2007950931120001@a09.dial.twics.com>,
  453. Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
  454. >Hi, Mac programming novice here with a question...
  455. >
  456. >The "Inside Mac" books say that, before setting the current port (when you
  457. >want to draw in it), you should save the previous port, then, after you
  458. >are done drawing, set it back to what it was.   (Written in a confusing
  459. >manner, I admit, but I think you know what I'm talking about.)
  460. >
  461. >My question: Is this really necessary?  If all code sets the port as
  462. >necessary before drawing in it, why bother to restore it?  Is there some
  463. >problem with asynchronous processing going on here?
  464.  
  465. Well, I almost never do this, myself, and I've never had any problems.  My
  466. personal programming policy is that it's every routine for itself as far as
  467. the port is concerned; if a routine is expecting the port to be
  468. such-and-such, it's that routine's responsibility to set it itself.  This
  469. saves me from having to trace back through a dozen routines to see who
  470. changed the port.
  471.  
  472. I _might_ make an exception (i.e. and save and restore the port) if I had
  473. some routine which did drawing in a certain port and was frequently called
  474. from within other routines which needed the port to be something in
  475. particular, so that calling this drawing routine would be transparent.  But
  476. in practice I find that I never need to do this.
  477.  
  478.   \/ __ __    _\_     --Sean Crist  (kurisuto@unagi.cis.upenn.edu)
  479.  ---  |  |    \ /     
  480.   _| ,| ,|   -----    For a free copy of the Bill of Rights, finger
  481.   _| ,| ,|    [_]     this account.
  482.    |  |  |    [_]     
  483.  
  484.  
  485.  
  486. +++++++++++++++++++++++++++
  487.  
  488. >From Charles B. Cranston <zben@ni.umd.edu>
  489. Date: 21 Jul 1995 18:22:23 GMT
  490. Organization: Network Infrastructures UMD CSC
  491.  
  492. > Is it really necessary to save and restore the current port
  493. > and set the desired port before and after any drawing?
  494.  
  495. I've used both philosophies:
  496.  
  497. 1. "Every routine for himself" - religiously set the port before any
  498.    drawing, the current port is irrelevant at any other time.
  499.    
  500. 2. "Keep the port set to the frontmost window" - religiosly set the
  501.    current port every activate, deactivate etc.
  502.  
  503. I remember back in the pre-Multifinder days (System 6) there was a
  504. Mac Tech Note describing a gotcha situation between applications and
  505. desk accessories (which USED to run in application space but were
  506. moved to Finder's space in Multifinder and System 7).
  507.  
  508. In the worst case, two badly coded DAs could crash each other without
  509. the application being able to do anything about it!  But there were
  510. other cases of DA vs application crashes that could be avoided if you
  511. made sure there was a valid current port befor giving the DA time.
  512.  
  513. I don't think this can happen anymore.  Anybody know?
  514.  
  515. +-+-+
  516. Charles B. (Ben) Cranston <zben@ni.umd.edu>
  517. http://www.wam.umd.edu/~zben
  518.  
  519. +++++++++++++++++++++++++++
  520.  
  521. >From mouser@zercom.net (Martin-Gilles Lavoie)
  522. Date: 24 Jul 1995 16:23:32 GMT
  523. Organization: zercom technologies inc.
  524.  
  525. In article <3uor8v$3b6@mimsy.cs.umd.edu>, Charles B. Cranston
  526. <zben@ni.umd.edu> wrote:
  527.  
  528. > > Is it really necessary to save and restore the current port
  529. > > and set the desired port before and after any drawing?
  530. > I've used both philosophies:
  531. > 1. "Every routine for himself" - religiously set the port before any
  532. >    drawing, the current port is irrelevant at any other time.
  533. >    
  534. > 2. "Keep the port set to the frontmost window" - religiosly set the
  535. >    current port every activate, deactivate etc.
  536. > I remember back in the pre-Multifinder days (System 6) there was a
  537. > Mac Tech Note describing a gotcha situation between applications and
  538. > desk accessories (which USED to run in application space but were
  539. > moved to Finder's space in Multifinder and System 7).
  540. > In the worst case, two badly coded DAs could crash each other without
  541. > the application being able to do anything about it!  But there were
  542. > other cases of DA vs application crashes that could be avoided if you
  543. > made sure there was a valid current port befor giving the DA time.
  544. > I don't think this can happen anymore.  Anybody know?
  545.  
  546. I've had extensions crewing up my view ports now and then.  Some still
  547. do.  I dont take a chance.  As to setting the port to every
  548. activate/deactivate events. this may be overkill (although, it doesn't
  549. take much CPU time..).  To be safe, I always set my port before drawing. 
  550. On activate, it'd be only usefull if I wanted to track the cursor position
  551. relative to the window position.
  552.  
  553. -- 
  554. Martin-Gilles Lavoie
  555.  
  556. MPW: Because life is too complicated for CodeWarrior.
  557. --MGL
  558.  
  559. +++++++++++++++++++++++++++
  560.  
  561. >From peter@adi.co.nz (Peter Bromley)
  562. Date: Sun, 23 Jul 1995 15:40:53 +1200
  563. Organization: ADInstruments
  564.  
  565. In article <3uo5g3$kbm@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
  566. (Sean Crist) wrote:
  567.  
  568. > In article <peter-2107951741260001@adi008.adi.co.nz>,
  569. > Peter Bromley <peter@adi.co.nz> wrote:
  570. > >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
  571. > >(Sean Crist) wrote:
  572. > >> Well, I almost never do this, myself, and I've never had any problems.  My
  573. > >> personal programming policy is that it's every routine for itself as far as
  574. > >> the port is concerned; if a routine is expecting the port to be
  575. > >> such-and-such, it's that routine's responsibility to set it itself.  This
  576. > >> saves me from having to trace back through a dozen routines to see who
  577. > >> changed the port.
  578. > >
  579. > >As if its all that difficult to do the right thing. All you need to do is
  580. > >use the GetPort, SetPort, code, SetPort combination as a response to the
  581. > >following things
  582. > *shrug*  I wasn't aware that this was an issue on which there is a "right"
  583. > way to do things.  Your way works, but I don't see what's wrong with my
  584. > way, as it works too, and doesn't violate any of Apple's rules (I think
  585. > they included GetPort so that you _can_ preserve the port, not because you
  586. > _have_ to).
  587.  
  588. Hmmmm, I guess I didnt express myself very clearly. And perhaps you are
  589. right - the NIM snippets dont seem to advocate protecting the current port
  590. at all. I guess my approach has arisin from discovering that whenever I
  591. found a current port related bug (like system font getting trashed, or
  592. LocalToGlobal doing weird things) I found that the port was not what I
  593. expected. My code policy evolved out from that to the (I guess) paranoid,
  594. but safe approach of making sure the port is what I want it to be but -
  595. just in case - always restoring the current port as well. I found it was
  596. easier to do this as close to my main event loop as possible and got the
  597. added bonus that lower level routines could assume the port was always
  598. correct.
  599.  
  600. BTW: these problems dont just come up with regard to the current port. I
  601. still find it difficult to setle on _one_ scheme for lots of other things,
  602. like pen and text settings within a port, foreground colour, and so on.
  603. The situation gets trickier, too, when you're not the only one working on
  604. a program. Differing approaches can cause lots of obscure bugs in a
  605. multi-person project ;-)
  606.  
  607. -- 
  608. Peter Bromley                                  (peter@adi.co.nz)
  609. ADInstruments, Dunedin, New Zealand            
  610.  
  611. +++++++++++++++++++++++++++
  612.  
  613. >From Richard Wesley <hawkfish@punchdeck.com>
  614. Date: 23 Jul 1995 23:28:17 GMT
  615. Organization: Punch Deck Consulting
  616.  
  617. peter@adi.co.nz (Peter Bromley) wrote:
  618. >In article <3umsqt$ocg@netnews.upenn.edu>, kurisuto@babel.ling.upenn.edu
  619. >(Sean Crist) wrote:
  620. >
  621. >> In article <duncant-2007950931120001@a09.dial.twics.com>,
  622. >> Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
  623. >> >Hi, Mac programming novice here with a question...
  624. >> >
  625. >> >The "Inside Mac" books say that, before setting the current port (when you
  626. >> >want to draw in it), you should save the previous port, then, after you
  627. >> >are done drawing, set it back to what it was.   (Written in a confusing
  628. >> >manner, I admit, but I think you know what I'm talking about.)
  629. >> >
  630. >> >My question: Is this really necessary?  If all code sets the port as
  631. >> >necessary before drawing in it, why bother to restore it?  Is there some
  632. >> >problem with asynchronous processing going on here?
  633. >> 
  634. >> Well, I almost never do this, myself, and I've never had any problems.  My
  635. >> personal programming policy is that it's every routine for itself as far as
  636. >> the port is concerned; if a routine is expecting the port to be
  637. >> such-and-such, it's that routine's responsibility to set it itself.  This
  638. >> saves me from having to trace back through a dozen routines to see who
  639. >> changed the port.
  640. >> 
  641. >
  642. >As if its all that difficult to do the right thing. All you need to do is
  643. >use the GetPort, SetPort, code, SetPort combination as a response to the
  644. >following things
  645. >
  646. >Events
  647. >     (update, activate, mousedown, keydown, appleevent),
  648. >Internal program "events"
  649. >     (idle, checkmouseshape, checknextWNEsleep, somedatachanged, dosomething)
  650. >
  651.  
  652. If you're using CW PowerPlant, you can even use the utility class StPortOriginState to save the state, then all you have to do is is=
  653. sue a declaration and C++ will clean it all up for you (even if an exception is thrown.)
  654.  
  655. If you're not using PP, just do something like
  656.  
  657. class StPortState {
  658.   GrafPtr mSave;
  659. public:
  660.  StPortState (GrafPtr inPort) {::GetPort (&mSave); ::SetPort (inPort);};
  661.  ~StPortState (void) {::SetPort (mSave);};
  662. };
  663.  
  664. and say 
  665.  
  666. StPortState savePort (myPort);
  667.  
  668. at the top of your routine.  No muss no fuss.
  669.  
  670. - rmgw
  671.  
  672. http://www.punchdeck.com/hawkfish/PunchDeck.html
  673.  
  674. - --------------------------------------------------------------------------
  675. Richard Wesley  hawkfish@punchdeck.com | "'Hand it round first, and cut it
  676. Punch Deck Consulting pnchdeck@aol.com |  afterwards.'" - Lewis Carroll,
  677.      Macintosh Software Development    |    "Through the Looking Glass"
  678. - --------------------------------------------------------------------------
  679.  
  680.  
  681.  
  682. +++++++++++++++++++++++++++
  683.  
  684. >From thor@telerama.lm.com (Tom Moertel)
  685. Date: Mon, 24 Jul 1995 22:50:05 -0500
  686. Organization: Management Science Associates, Commercial Software Group
  687.  
  688. Regarding the age-old controversy of whether or not to save and restore
  689. the drawing environment, I look to a higher question:  Sould we know where
  690. we are drawing?
  691.  
  692. The obvious answer is yes.  We ought to know where we are drawing.  To
  693. draw haphazardly is to discard order and consistency, to cast away the
  694. foundation of the Macintosh environment.  Thus we create The Fundamental
  695. Axiom of Drawing:  We should always know where we are drawing.
  696.  
  697. Now, can we derive from the Axiom simple rules ensuring that our code will
  698. always do the right thing?  You betcha.
  699.  
  700. *** Rule 1 ***  Before drawing in an independent routine, explicitly set
  701. the drawing environment.
  702.  
  703. Rule 1 ensures that when your routine draws, it knows where it is drawing.
  704.  
  705. But we still have a problem.  What about the routine that called your
  706. drawing routine?  When your routine returns, how can we ensure that the
  707. caller will still be drawing where it thinks it is?  Rule 2 gives the
  708. answer:
  709.  
  710. *** Rule 2 ***  If your routine changes the drawing environment, make sure
  711. it restores the environment before returning to the caller.
  712.  
  713. Rule 2 ensures that if the caller knew where it was drawing when it called
  714. your routine, it will still know where it is drawing when it regains
  715. control (because it is drawing in the same place).
  716.  
  717. These two rules are sufficient to ensure consistency with the Fundamental
  718. Axiom.  If you follow them, your code will always draw in the right place,
  719. and the world will be more enjoyable for all.
  720.  
  721. -- 
  722. Tom Moertel
  723. thor@telerama.lm.com
  724.  
  725. +++++++++++++++++++++++++++
  726.  
  727. >From carl.gustafson@ece.drexel.edu (Carl Gustafson)
  728. Date: 24 Jul 1995 13:21:42 GMT
  729. Organization: Imaging and Computer Vision Center, Drexel University
  730.  
  731. In article <peter-2307951540530001@adi008.adi.co.nz>, peter@adi.co.nz
  732. (Peter Bromley) wrote:
  733.  
  734.  
  735. > Hmmmm, I guess I didnt express myself very clearly. And perhaps you are
  736. > right - the NIM snippets dont seem to advocate protecting the current port
  737. > at all. I guess my approach has arisin from discovering that whenever I
  738. > found a current port related bug (like system font getting trashed, or
  739. > LocalToGlobal doing weird things) I found that the port was not what I
  740. > expected. My code policy evolved out from that to the (I guess) paranoid,
  741. > but safe approach of making sure the port is what I want it to be but -
  742. > just in case - always restoring the current port as well. I found it was
  743. > easier to do this as close to my main event loop as possible and got the
  744. > added bonus that lower level routines could assume the port was always
  745. > correct.
  746. > BTW: these problems dont just come up with regard to the current port. I
  747. > still find it difficult to setle on _one_ scheme for lots of other things,
  748. > like pen and text settings within a port, foreground colour, and so on.
  749. > The situation gets trickier, too, when you're not the only one working on
  750. > a program. Differing approaches can cause lots of obscure bugs in a
  751. > multi-person project ;-)
  752.  
  753. I've always considered preserving and restoring the grafport, pen
  754. settings, handle lock settings, etc. to be good, defensive programming.
  755. (Mostly defensive against myself, but that's another matter.) It may be a
  756. PITA to develop the habit, and take an extra minute to paste in the code,
  757. but it can save much cleanup time later.
  758.  
  759. -- 
  760. Carl Gustafson
  761. Imaging and Computer Vision Center
  762. Drexel University, Philadelphia, Penna
  763. - ----------------------------------------------------------
  764. I don't speak for Drexel, and Drexel doesn't listen to me...
  765.  
  766. +++++++++++++++++++++++++++
  767.  
  768. >From Jim.Spencer@p510.f61.n282.z1.fidonet.org (Jim Spencer)
  769. Date: 23 Jul 95 10:58:27 
  770. Organization: Magical Mystery
  771.  
  772. On 7/21/95, kurisuto@babel.ling.upenn.edu emerged from Plato's cave and
  773. expounded the following to  All
  774.  
  775.   ku> *shrug*  I wasn't aware that this was an issue on which there is a
  776.   ku> "right" way to do things.  Your way works, but I don't see what's
  777.   ku> wrong with my way, as it works too, and doesn't violate any of Apple's
  778.   ku> rules (I think they included GetPort so that you _can_ preserve the
  779.   ku> port, not because you _have_ to).
  780.  
  781. No, there is a right way.  Your code is not the only one using QuickDraw, the
  782. toolbox itself is if no one else.
  783.  
  784.   ku> Really, I think it's personal preference, and the important thing is
  785.   ku> that you pick a scheme and then _be consistant_ with it.  Since none
  786.   ku> of my routines make assumptions about what the port should be (with a
  787.   ku> very few exceptions which I always document clearly in my comments),
  788.   ku> none of them need to preserve it either, and I never run into trouble.
  789.  
  790. Until the toolbox thinks that the port is set to one thing and in fact it's
  791. set 
  792. to another then CRASH.
  793.  
  794.   > I _might_ make an exception (i.e. and save and restore the port) if I
  795.   > had some routine which did drawing in a certain port and was frequently
  796.   > called from within other routines which needed the port to be something
  797.   > in particular, so that calling this drawing routine would be
  798.   > transparent.  But in practice I find that I never need to do this.
  799.   > 
  800.   > See, if you did it _right_, you wouldnt ever need to protect individual
  801.   > routines ever.
  802.   > 
  803.   > BTW: If IM says do something, you'ld have to be a fool or an expert to
  804.   > do otherwise (IMO of course).
  805.   > 
  806.   ku> I agree that IM should be rigorously followed.  But I don't agree that
  807.   ku> I'm outside IM's rules here.  I'd be quite shocked to learn that IM
  808.   ku> somewhere says "If your routines change the port internally, they must
  809.   ku> always remember and restore the current port, and if you don't do
  810.   ku> this, your application is likely to break under future system
  811.   ku> releases."  The important point is that the port be correctly set at
  812.   ku> times when it matters, and there's more than one overall scheme for
  813.   ku> ensuring that this is so.
  814.   
  815. This issue is the same as checking for errors.  It's a question of how bullet
  816.  
  817. proof you want your code to be.  If you restore the port in your drawing 
  818. functions then it doesn't matter what happens elsewhere.  You are making
  819. assumptions which at best can only be called sloppy in particular that you
  820. won't make a mistake as your code get's more complicated (I'll grant you this
  821. isn't much of an issue in a "Hello World!" program but how about in something
  822. exceeding 100,000 lines??) and that no one other than you will ever work with
  823. your code.  IMHO, you can only be sure that both will be true if you are
  824. doing
  825. essentially trivial programs.
  826.  
  827. +++++++++++++++++++++++++++
  828.  
  829. >From peter@adi.co.nz (Peter Bromley)
  830. Date: Wed, 26 Jul 1995 18:51:11 +1200
  831. Organization: ADInstruments
  832.  
  833. In article <mouser-2407951158400001@204.191.6.123>, mouser@zercom.net
  834. (Martin-Gilles Lavoie) wrote:
  835.  
  836. [SNIP]
  837. > I've had extensions crewing up my view ports now and then....
  838.  
  839. Ouch!!!
  840.  
  841. > ...  Some still
  842. > do.  I dont take a chance.  As to setting the port to every
  843. > activate/deactivate events. this may be overkill (although, it doesn't
  844. > take much CPU time..).  To be safe, I always set my port before drawing. 
  845. > On activate, it'd be only usefull if I wanted to track the cursor position
  846. > relative to the window position.
  847.  
  848. One of the most common reactions to (de)activate is to add or remove a
  849. selection (esp calling TEActivate). The current port needs to be set
  850. correctly for these things to draw right (although TEActivate might be
  851. paranoid)
  852.  
  853. Just another $0.02,
  854.  
  855. -- 
  856. Peter Bromley                                  (peter@adi.co.nz)
  857. ADInstruments, Dunedin, New Zealand            
  858.  
  859. +++++++++++++++++++++++++++
  860.  
  861. >From peter@stairways.com.au (Peter N Lewis)
  862. Date: Thu, 27 Jul 1995 20:07:41 +0800
  863. Organization: Stairways Software
  864.  
  865. In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
  866. (Tom Moertel) wrote:
  867.  
  868. >The obvious answer is yes.  We ought to know where we are drawing.  To
  869. >draw haphazardly is to discard order and consistency, to cast away the
  870. >foundation of the Macintosh environment.  Thus we create The Fundamental
  871. >Axiom of Drawing:  We should always know where we are drawing.
  872.  
  873. >*** Rule 1 ***  Before drawing in an independent routine, explicitly set
  874. >the drawing environment.
  875.  
  876. >*** Rule 2 ***  If your routine changes the drawing environment, make sure
  877. >it restores the environment before returning to the caller.
  878.  
  879. Rule 2 is redundant and not necessary (and ignoring it leads to Sean
  880. Crist's way of doing it (which is the same as mine, and contrary to
  881. popular wisdom).
  882.  
  883. If you draw something, ensure the port is set correctly (Rule 1).  If you
  884. call another routine which may change the port, then re-apply Rule 1.
  885.  
  886. Obviously, if you are messing around with trap patching and the like, then
  887. you want to preserve *everything*.  Also, if you are in a library routine
  888. that shouldn't be messing with the port, but does in strange cases, or a
  889. callback from the OS or something like that where the caller is out of
  890. your control, then it is defnsive to restore the port.
  891.  
  892. However, it is not necessarily safe to do so.  For example, consider this code:
  893.  
  894. wp := NewWindow
  895. SetPort(wp)
  896. CloseWindow(wp)
  897. CallYourRoutine
  898.  
  899. If CallYourRoutine does as suggested by popular wisdom, then it will save
  900. and restore the port - but the port is currently invalid, so the trailing
  901. SetPort(savedport) call will be invalid and potentially dangerous!  More
  902. important than Rule 2 is that you should never call SetPort (or any other
  903. OS routine) with invalid parameters.
  904. Enjoy,
  905.    Peter.
  906. -- 
  907. It's still easy in Unix:
  908.         ls *.lisp | sed -e 's/\(.*\).lisp$/mv "\1.lisp" "\1.lst"/' | sh
  909. --Tim Smith <tzs@u.washington.edu>
  910.  
  911. +++++++++++++++++++++++++++
  912.  
  913. >From thor@telerama.lm.com (Tom Moertel)
  914. Date: Fri, 28 Jul 1995 00:49:15 -0500
  915. Organization: Management Science Associates, Commercial Software Group
  916.  
  917. In article <peter-2707952007420001@zany.peter.com.au>,
  918. peter@stairways.com.au (Peter N Lewis) wrote:
  919.  
  920. > In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
  921. > (Tom Moertel) wrote:
  922. > > [SNIP]  Thus we create The Fundamental
  923. > > Axiom of Drawing:  We should always know where we are drawing.
  924. > >*** Rule 1 ***  Before drawing in an independent routine, explicitly set
  925. > >the drawing environment.
  926. > >*** Rule 2 ***  If your routine changes the drawing environment, make sure
  927. > >it restores the environment before returning to the caller.
  928. > Rule 2 is redundant and not necessary (and ignoring it leads to Sean
  929. > Crist's way of doing it (which is the same as mine, and contrary to
  930. > popular wisdom).
  931. > If you draw something, ensure the port is set correctly (Rule 1).  If you
  932. > call another routine which may change the port, then re-apply Rule 1.
  933.  
  934. If I call a routine that I suspect will muck up the drawing environment, I
  935. do as you suggest and re-apply rule 1.  That's defensive programming. 
  936. However, I draw the line at repeatedly applying rule 1 as my primary
  937. method of esuring that my code is drawing in the right place with the
  938. right settings.  There are three reasons for my preference:
  939.  
  940. (1) Applying Rule 1 can be costly.  If a routine has special requirements
  941.     for the pen, text face, text size, and so on, repeatedly enforcing
  942.     those requirements can be excessive.
  943.  
  944. (2) Because of (1), we might be tempted to examine a subroutine before
  945.     calling it just to see what parts of the graphics environment it
  946.     changes, in hopes of have to restore only those parts.  Our calling
  947.     routine would thus become dependent on the implementation details
  948.     of the subroutine.  I try to reduce dependancy when possible.
  949.  
  950. (3) Alternatively, we could try to reduce the costs mentioned in (1)
  951.     by having overly graphic subroutines clean up after themselves (in
  952.     essence, applying Rule 2).  In that way, callers would need to re-apply
  953.     Rule 1 only to the more commonly changed graphics variables.  I
  954.     don't like this arrangement because it's inconsistent.  Sometimes
  955.     we use a re-application of Rule 1 and sometimes we use Rule 1 in
  956.     conjunction with Rule 2.  That's too confusing for my meager
  957.     brain to handle in the midnight hours, when otherwise good hackin'
  958.     might be disrupted by too much thinkin' ;-)
  959.  
  960. > Obviously, if you are messing around with trap patching and the like, then
  961. > you want to preserve *everything*.  Also, if you are in a library routine
  962. > that shouldn't be messing with the port, but does in strange cases, or a
  963. > callback from the OS or something like that where the caller is out of
  964. > your control, then it is defnsive to restore the port.
  965. >
  966. > However, it is not necessarily safe to do so.  For example, consider
  967. this code:
  968. > wp := NewWindow
  969. > SetPort(wp)
  970. > CloseWindow(wp)
  971. > CallYourRoutine
  972. > If CallYourRoutine does as suggested by popular wisdom, then it will save
  973. > and restore the port - but the port is currently invalid, so the trailing
  974. > SetPort(savedport) call will be invalid and potentially dangerous!
  975.  
  976. Hey, that's not fair! ;-)  The way I see it, you could remove
  977. CallYourRoutine altogether and the port will still be hosed.  That is,
  978. unless you think it's a good idea to have CallYourRoutine, a subroutine,
  979. set up its caller's port as a side effect of its normal operation.
  980.  
  981. In this case it's clear that if the program wants to draw after it called
  982. CloseWindow, it had better set up the drawing environment -- regardless of
  983. what CallYourRoutine does.  What's interesting is that even in this
  984. example, where the port is hosed, CallYourRoutine would have drawn
  985. properly if it been written with both Rule 1 and Rule 2 in mind.
  986.  
  987. > More
  988. > important than Rule 2 is that you should never call SetPort (or any other
  989. > OS routine) with invalid parameters.
  990.  
  991. Agreed.  But it's hard to ensure that your parameters will always be good
  992. without the help of a couple rules....
  993.  
  994. Cheers and fine homebrew,
  995. Tom
  996.  
  997. -- 
  998. Tom Moertel
  999. thor@telerama.lm.com
  1000.  
  1001. +++++++++++++++++++++++++++
  1002.  
  1003. >From Mark Williams <Mark@streetly.demon.co.uk>
  1004. Date: Thu, 27 Jul 95 09:37:56 GMT
  1005. Organization: Streetly Software
  1006.  
  1007.  
  1008. In article <c1b_9507250800@mmbbs.com>, Jim Spencer writes:
  1009.  
  1010. > On 7/21/95, kurisuto@babel.ling.upenn.edu emerged from Plato's cave and
  1011. > expounded the following to  All
  1012. >   ku> *shrug*  I wasn't aware that this was an issue on which there is a
  1013. >   ku> "right" way to do things.  Your way works, but I don't see what's
  1014. >   ku> wrong with my way, as it works too, and doesn't violate any of Apple's
  1015. >   ku> rules (I think they included GetPort so that you _can_ preserve the
  1016. >   ku> port, not because you _have_ to).
  1017. > No, there is a right way.  Your code is not the only one using QuickDraw, the
  1018. > toolbox itself is if no one else.
  1019. >   ku> Really, I think it's personal preference, and the important thing is
  1020. >   ku> that you pick a scheme and then _be consistant_ with it.  Since none
  1021. >   ku> of my routines make assumptions about what the port should be (with a
  1022. >   ku> very few exceptions which I always document clearly in my comments),
  1023. >   ku> none of them need to preserve it either, and I never run into trouble.
  1024. > Until the toolbox thinks that the port is set to one thing and in fact it's
  1025. > set 
  1026. > to another then CRASH.
  1027.  
  1028. Well, the only toolbox call I can think of which requires a particular port to be set (other than 
  1029. the obvious quickdraw calls) is ModalDialog, and thats always struck me as a mistake in the 
  1030. documentation - last time I checked it operates on the FrontWindow() not the current port, BWTFDIK.
  1031.  
  1032. I suppose the exceptions are callback routines and DefProcs - but here the documentation is 
  1033. (usually) very specific about what you need to save and restore.
  1034.  
  1035. That objection aside (please dont bother sending me lists of toolbox calls which require a 
  1036. particular port to be set), I still dont follow the logic here. There _are_ times when a certain 
  1037. port needs to be set - so you just set it. What has that got to do with saving and restoring the 
  1038. port?
  1039.  
  1040. Look at the way PowerPlant and TCL (and possibly MacApp - I wouldnt know) handle setting the port. 
  1041. There is a routine (Prepare, or FocusView - whatever) which sets up the port and coordinate system. 
  1042. It gets called whenever a particular view needs to be setup - the frameworks make no attempt to save 
  1043. the current port. More significantly, since all the views in a window share a single port, _just_ 
  1044. saving and restoring the port will do you no good at all - you lose the origin, clipping region and 
  1045. any other view-specific environment info (font, pen size, colours etc).
  1046.  
  1047. > [snip]  
  1048. > This issue is the same as checking for errors.  It's a question of how bullet
  1049. > proof you want your code to be.  If you restore the port in your drawing 
  1050. > functions then it doesn't matter what happens elsewhere.  You are making
  1051. > assumptions which at best can only be called sloppy in particular that you
  1052. > won't make a mistake as your code get's more complicated (I'll grant you this
  1053. > isn't much of an issue in a "Hello World!" program but how about in something
  1054. > exceeding 100,000 lines??) and that no one other than you will ever work with
  1055. > your code.  IMHO, you can only be sure that both will be true if you are
  1056. > doing
  1057. > essentially trivial programs.
  1058.  
  1059. Wow.
  1060.  
  1061. All TCL and PowerPlant apps are trivial.
  1062.  
  1063. - --------------------------------------
  1064. Mark Williams<Mark@streetly.demon.co.uk>
  1065.  
  1066. +++++++++++++++++++++++++++
  1067.  
  1068. >From ldo@waikato.ac.nz (Lawrence D’Oliveiro)
  1069. Date: Fri, 28 Jul 1995 19:53:13 +1200
  1070. Organization: University of Waikato
  1071.  
  1072. In article <peter-2707952007420001@zany.peter.com.au>,
  1073. peter@stairways.com.au (Peter N Lewis) wrote:
  1074.  
  1075. >However, it is not necessarily safe to do so.  For example, consider this code:
  1076. >
  1077. >wp := NewWindow
  1078. >SetPort(wp)
  1079. >CloseWindow(wp)
  1080. >CallYourRoutine
  1081. >
  1082. >If CallYourRoutine does as suggested by popular wisdom, then it will save
  1083. >and restore the port - but the port is currently invalid, so the trailing
  1084. >SetPort(savedport) call will be invalid and potentially dangerous!
  1085.  
  1086. I disagree. I don't think there is anything wrong with doing a SetPort to
  1087. an invalid port, just so long as you don't try to draw to it. And if every
  1088. piece of code is explicitly doing a SetPort before doing their drawing,
  1089. you'll never hit the problem!
  1090.  
  1091. Consider also what happens after the initial InitGraf call: the current
  1092. port is undefined then, too.
  1093.  
  1094. In short, it seems to me the current semantics of SetPort is: it's OK to
  1095. use it to restore whatever value you previously got from GetPort, even if
  1096. that value is not a valid port. Somehow I don't think that aspect of the
  1097. semantics will ever change, since it just makes things too complicated
  1098. otherwise.
  1099.  
  1100. Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
  1101.  
  1102. +++++++++++++++++++++++++++
  1103.  
  1104. >From stk@berlin.snafu.de (Stefan Kurth)
  1105. Date: Fri, 28 Jul 1995 13:22:43 +0200
  1106. Organization: none
  1107.  
  1108. Peter N Lewis <peter@stairways.com.au> wrote:
  1109.  
  1110. > In article <thor-2407952250050001@thor.slip.lm.com>, thor@telerama.lm.com
  1111. > (Tom Moertel) wrote:
  1112. >
  1113. > >*** Rule 1 ***  Before drawing in an independent routine, explicitly set
  1114. > >the drawing environment.
  1115. >
  1116. > >*** Rule 2 ***  If your routine changes the drawing environment, make sure
  1117. > >it restores the environment before returning to the caller.
  1118. >
  1119. > Rule 2 is redundant and not necessary (and ignoring it leads to Sean
  1120. > Crist's way of doing it (which is the same as mine, and contrary to
  1121. > popular wisdom).
  1122. >
  1123. > If you draw something, ensure the port is set correctly (Rule 1).  If you
  1124. > call another routine which may change the port, then re-apply Rule 1.
  1125.  
  1126. Peter, I can't believe that you wrote this.  No offence, but this has
  1127. very little to do with modern programming techniques.  It requires that
  1128. for every routine that you call you have to know whether it can possibly
  1129. change the current port.  This is not desirable, especially in multi-
  1130. person projects.
  1131.  
  1132. A much better design is to make sure that none of your routines have any
  1133. side effects whatsoever, like changing global variables, or changing the
  1134. drawing environment or the current port (which is just a global variable
  1135. after all).
  1136.  
  1137. Suppose you have something like this:
  1138.  
  1139. SetPort(myWindow);
  1140. /* draw something here */
  1141. SomeRoutine();
  1142. /* draw something else here */
  1143.  
  1144. You don't set the port again after SomeRoutine(), because you know that
  1145. this routine doesn't change the port.  Now, 1/2 year later you make
  1146. modifications to SomeRoutine so that it now does change the current port
  1147. for some reason (or calls another routine that does).  So you now have
  1148. to go through your entire program, find all calls to SomeRoutine, and
  1149. insert SetPort's all over the place.  Frankly, I wouldn't want to have
  1150. to maintain your program.
  1151.  
  1152. > wp := NewWindow
  1153. > SetPort(wp)
  1154. > CloseWindow(wp)
  1155. > CallYourRoutine
  1156. >
  1157. > If CallYourRoutine does as suggested by popular wisdom, then it will save
  1158. > and restore the port - but the port is currently invalid, so the trailing
  1159. > SetPort(savedport) call will be invalid and potentially dangerous!  More
  1160. > important than Rule 2 is that you should never call SetPort (or any other
  1161. > OS routine) with invalid parameters.
  1162.  
  1163. There is nothing to worry about here.  Invalid parameter?  Maybe, but we
  1164. got that parameter from GetPort earlier, so it must be valid enough for
  1165. the OS.  And whether the port was valid before we were called, or will
  1166. be valid after we return, is not something we should care about.  We
  1167. just set everything back to what it was, and this is no more dangerous
  1168. than if we hadn't been called at all.
  1169.  
  1170. The only place where you would have to worry about the port being
  1171. invalid is in the routine that calls CloseWindow, but nowhere else.
  1172.  
  1173. ________________________________________________________________________
  1174. Stefan Kurth               Berlin, Germany           stk@berlin.snafu.de
  1175.  
  1176. +++++++++++++++++++++++++++
  1177.  
  1178. >From mhl@icf.hrb.com (Mark H. Linton)
  1179. Date: 27 Jul 95 18:00:55 EST
  1180. Organization: HRB Systems, Inc.
  1181.  
  1182. In article <thor-2407952250050001@thor.slip.lm.com>, 
  1183.    thor@telerama.lm.com (Tom Moertel) wrote:
  1184.  
  1185. >Thus we create The Fundamental Axiom of Drawing:  
  1186. >   We should always know where we are drawing.
  1187. >*** Rule 1 ***  Before drawing in an independent routine, explicitly set
  1188. >the drawing environment.
  1189. >*** Rule 2 ***  If your routine changes the drawing environment, make sure
  1190. >it restores the environment before returning to the caller.
  1191.  
  1192. I am afraid I agree with Tom on this.
  1193.  
  1194. Just to get all of you who are less than defensive, I am going to
  1195. write an extension which installs a global jGNE filter -- whose
  1196. only purpose in life is to:
  1197.  
  1198. a) screw up the current graphics port (i.e. set it to something
  1199. other than it was before)
  1200.  
  1201. b) screw up the graphics pen (e.g., set its width to 32768 x
  1202. 32768, etc.)
  1203.  
  1204. If your screen doesn't get wacky, then your coding technique
  1205. obviously works. Otherwise not...
  1206.  
  1207. BTW, the suggested Get, Set, Draw, Set sequence will always work
  1208. in a cooperative multitasking environment in the presence of such
  1209. a filter.
  1210.  
  1211. -- 
  1212. Hope this helps.
  1213.  
  1214. Mark H. Linton
  1215. ____________________________________________________________________
  1216. mark \'märk\ n [ME, fr. OE mearc boundary, march, sign; akin to OHG
  1217. marha boundary, L margo] 1 a : a conspicuous object serving as a guide
  1218. for travelers 2 : A standard or criterion of quality 3 : An object or
  1219. point that serves as a guide --idiom. mark time. 1 : To make little or
  1220. no progress
  1221.  
  1222. +++++++++++++++++++++++++++
  1223.  
  1224. >From pottier@jonque.ens.fr (Francois Pottier)
  1225. Date: 28 Jul 1995 15:10:19 GMT
  1226. Organization: Ecole Normale Superieure, Paris
  1227.  
  1228. In article <thor-2807950049150001@thor.slip.lm.com>,
  1229. Tom Moertel <thor@telerama.lm.com> wrote:
  1230.  
  1231. >(1) Applying Rule 1 can be costly.  If a routine has special requirements
  1232. >    for the pen, text face, text size, and so on, repeatedly enforcing
  1233. >    those requirements can be excessive.
  1234. >
  1235. >(2) Because of (1), we might be tempted to examine a subroutine before
  1236. >    calling it just to see what parts of the graphics environment it
  1237. >    changes, in hopes of have to restore only those parts.
  1238.  
  1239. I understand these problems. I suggest you have a look at the way they
  1240. are handled in PowerPlant. PowerPlant only uses Rule 1. This means that
  1241. no assumptions are made about the current port, and a routine has to
  1242. set the graphic environment by calling FocusDraw() before drawing.
  1243. So a PowerPlant program ends up calling FocusDraw() many times. But 
  1244. the implementation of FocusDraw() remembers if it has already been
  1245. called, so it costs almost nothing to call it too often. I think it's
  1246. a good solution.
  1247.  
  1248. -- 
  1249. Francois Pottier                                            pottier@dmi.ens.fr
  1250. - ----------------------------------------------------------------------------
  1251. Check my WWW page at http://acacia.ens.fr:8080/home/pottier/ ...
  1252.  
  1253. +++++++++++++++++++++++++++
  1254.  
  1255. >From pottier@jonque.ens.fr (Francois Pottier)
  1256. Date: 28 Jul 1995 15:15:55 GMT
  1257. Organization: Ecole Normale Superieure, Paris
  1258.  
  1259. In article <1995072813224396868@stk.berlin.snafu.de>,
  1260. Stefan Kurth <stk@berlin.snafu.de> wrote:
  1261.  
  1262. >> If you draw something, ensure the port is set correctly (Rule 1).  If you
  1263. >> call another routine which may change the port, then re-apply Rule 1.
  1264. >
  1265. >Peter, I can't believe that you wrote this.  No offence, but this has
  1266. >very little to do with modern programming techniques.  It requires that
  1267. >for every routine that you call you have to know whether it can possibly
  1268. >change the current port.  This is not desirable, especially in multi-
  1269. >person projects.
  1270.  
  1271. I agree that it is not desirable - but it is *not* necessary. Just
  1272. assume that *every* subroutine changes the port. Always set it before
  1273. drawing.
  1274.  
  1275. As I pointed out in another message, setting the graphics environment
  1276. every time you think it might have changed is not costly if you have
  1277. a smart implementation. Look at PowerPlant - it remembers which pane
  1278. is currently in focus.
  1279.  
  1280. About the port being invalid, it's nothing to worry about, as long as
  1281. you apply rule 1 and set it before drawing.
  1282.  
  1283. Cheers,
  1284.  
  1285.  
  1286.  
  1287. -- 
  1288. Francois Pottier                                            pottier@dmi.ens.fr
  1289. - ----------------------------------------------------------------------------
  1290. Check my WWW page at http://acacia.ens.fr:8080/home/pottier/ ...
  1291.  
  1292. +++++++++++++++++++++++++++
  1293.  
  1294. >From ingemar@lysator.liu.se (Ingemar Ragnemalm)
  1295. Date: 29 Jul 1995 19:22:39 GMT
  1296. Organization: (none)
  1297.  
  1298. >>> Duncan Thomson <duncant@sushi.mitre.or.jp> wrote:
  1299. >>> >Hi, Mac programming novice here with a question...
  1300. >>> >
  1301. >>> >The "Inside Mac" books say that, before setting the current port (when you
  1302. >>> >want to draw in it), you should save the previous port, then, after you
  1303. >>> >are done drawing, set it back to what it was.   (Written in a confusing
  1304. >>> >manner, I admit, but I think you know what I'm talking about.)
  1305. >>> >
  1306. >>> >My question: Is this really necessary?  If all code sets the port as
  1307. >>> >necessary before drawing in it, why bother to restore it?  Is there some
  1308. >>> >problem with asynchronous processing going on here?
  1309.  
  1310. No, you don't HAVE to restore the port, but it is a very good habit. If all
  1311. utility functions, routines that fire up dialogs etc, restore the port, you
  1312. can call them any time. If you are careless, you will have to put SetPort's
  1313. all over the place.
  1314.  
  1315. --
  1316. - -
  1317. Ingemar Ragnemalm, PhD
  1318. Image processing, Mac shareware games
  1319. E-mail address: ingemar@isy.liu.se or ingemar@lysator.liu.se
  1320.  
  1321. +++++++++++++++++++++++++++
  1322.  
  1323. >From kenp@nmrfam.wisc.edu (Ken Prehoda)
  1324. Date: Tue, 01 Aug 1995 10:00:42 -0500
  1325. Organization: Univ of Wisc-Madison, Dept of Biochemistry
  1326.  
  1327. In article <ldo-2807951953130001@130.217.96.144>, ldo@waikato.ac.nz wrote:
  1328.  
  1329. : In article <peter-2707952007420001@zany.peter.com.au>,
  1330. : peter@stairways.com.au (Peter N Lewis) wrote:
  1331. : >However, it is not necessarily safe to do so.  For example, consider
  1332. this code:
  1333. : >
  1334. : >wp := NewWindow
  1335. : >SetPort(wp)
  1336. : >CloseWindow(wp)
  1337. : >CallYourRoutine
  1338. : >
  1339. : >If CallYourRoutine does as suggested by popular wisdom, then it will save
  1340. : >and restore the port - but the port is currently invalid, so the trailing
  1341. : >SetPort(savedport) call will be invalid and potentially dangerous!
  1342. : I disagree. I don't think there is anything wrong with doing a SetPort to
  1343. : an invalid port, just so long as you don't try to draw to it. And if every
  1344. : piece of code is explicitly doing a SetPort before doing their drawing,
  1345. : you'll never hit the problem!
  1346. : Consider also what happens after the initial InitGraf call: the current
  1347. : port is undefined then, too.
  1348. : In short, it seems to me the current semantics of SetPort is: it's OK to
  1349. : use it to restore whatever value you previously got from GetPort, even if
  1350. : that value is not a valid port. Somehow I don't think that aspect of the
  1351. : semantics will ever change, since it just makes things too complicated
  1352. : otherwise.
  1353. : Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
  1354.  
  1355. It all depends on how you use Quickdraw GX.  If you use the:
  1356.  
  1357. gxRectangle rectGeom = {...};
  1358. gxShape rect = GXNewRectangle(&rectGeom);
  1359. GXSetShapeViewPorts(rect,...);
  1360.  
  1361. method, then sure you don't have to worry about the "current port".  But
  1362. there is the disadvantage of creating an object in the GX heap that you
  1363. could potentially leave around for awhile.
  1364.  
  1365. GX also has these types of calls though:
  1366.  
  1367. gxRectangle rectGeom = {...};
  1368.  
  1369. GXDrawRectangle(&rectGeom,...);
  1370.  
  1371. and if you use these types, then you certainly do have to worry about the
  1372. "current port" (or default shapes as they are called in GX).  It is also
  1373. interesting to note that these calls are quite a bit faster than the ones
  1374. given in the above example.
  1375.  
  1376. -- 
  1377. Ken Prehoda, kenp@nmrfam.wisc.edu
  1378.  
  1379. +++++++++++++++++++++++++++
  1380.  
  1381. >From kenp@nmrfam.wisc.edu (Ken Prehoda)
  1382. Date: Tue, 01 Aug 1995 10:00:42 -0500
  1383. Organization: Univ of Wisc-Madison, Dept of Biochemistry
  1384.  
  1385. In article <ldo-2807951953130001@130.217.96.144>, ldo@waikato.ac.nz wrote:
  1386.  
  1387. : In article <peter-2707952007420001@zany.peter.com.au>,
  1388. : peter@stairways.com.au (Peter N Lewis) wrote:
  1389. : >However, it is not necessarily safe to do so.  For example, consider
  1390. this code:
  1391. : >
  1392. : >wp := NewWindow
  1393. : >SetPort(wp)
  1394. : >CloseWindow(wp)
  1395. : >CallYourRoutine
  1396. : >
  1397. : >If CallYourRoutine does as suggested by popular wisdom, then it will save
  1398. : >and restore the port - but the port is currently invalid, so the trailing
  1399. : >SetPort(savedport) call will be invalid and potentially dangerous!
  1400. : I disagree. I don't think there is anything wrong with doing a SetPort to
  1401. : an invalid port, just so long as you don't try to draw to it. And if every
  1402. : piece of code is explicitly doing a SetPort before doing their drawing,
  1403. : you'll never hit the problem!
  1404. : Consider also what happens after the initial InitGraf call: the current
  1405. : port is undefined then, too.
  1406. : In short, it seems to me the current semantics of SetPort is: it's OK to
  1407. : use it to restore whatever value you previously got from GetPort, even if
  1408. : that value is not a valid port. Somehow I don't think that aspect of the
  1409. : semantics will ever change, since it just makes things too complicated
  1410. : otherwise.
  1411. : Lawrence "QuickDraw GX doesn't have this problem" D'Oliveiro
  1412.  
  1413. It all depends on how you use Quickdraw GX.  If you use the:
  1414.  
  1415. gxRectangle rectGeom = {...};
  1416. gxShape rect = GXNewRectangle(&rectGeom);
  1417. GXSetShapeViewPorts(rect,...);
  1418.  
  1419. method, then sure you don't have to worry about the "current port".  But
  1420. there is the disadvantage of creating an object in the GX heap that you
  1421. could potentially leave around for awhile.
  1422.  
  1423. GX also has these types of calls though:
  1424.  
  1425. gxRectangle rectGeom = {...};
  1426.  
  1427. GXDrawRectangle(&rectGeom,...);
  1428.  
  1429. and if you use these types, then you certainly do have to worry about the
  1430. "current port" (or default shapes as they are called in GX).  It is also
  1431. interesting to note that these calls are quite a bit faster than the ones
  1432. given in the above example.
  1433.  
  1434. -- 
  1435. Ken Prehoda, kenp@nmrfam.wisc.edu
  1436.  
  1437. ---------------------------
  1438.  
  1439. >From tmorrow@us.oracle.com (tmorrow)
  1440. Subject: Where are my command line arguments?
  1441. Date: 29 Jul 1995 00:19:26 GMT
  1442. Organization: Oracle Corporation. Redwood Shores, CA
  1443.  
  1444.  
  1445. We are in the process of porting some batch programs over to the
  1446. Macintosh from UNIX, and realizing that the Mac has no command line
  1447. argument interface for invoking executables.
  1448.  
  1449. This is a major bummer, and are curious about what other people have
  1450. done in this type of situation.
  1451.  
  1452. We basically have one program which sequentially spawns processes to do
  1453. various batch type tasks, communicating important paramters to the
  1454. child processes through the command line.  We have thought of using
  1455. files to communicate the same information that we communicated on the
  1456. command line in UNIX.  The files would be the documents in Mac's
  1457. document-centric interface; invoking (opening) a file of command line
  1458. arguments would be equivalent to invoking an application with those
  1459. command line arguments on UNIX.  Another idea would be apple events,
  1460. but that would probably require even more "nativising" which we don't
  1461. want to do if we don't have to.
  1462.  
  1463. Is there some kind of library or some other simple solution that won't
  1464. require as much native coding as using files of arguments or passing
  1465. the arguments through apple events?  Ideally there would be a way to
  1466. keep the argc, argv processing code just the way it is on UNIX.
  1467.  
  1468. It seems like a glaring deficiency that the Mac has no way of passing
  1469. paramters to an application upon startup, but I guess that is due to
  1470. its document-centric design, eh?
  1471.  
  1472. Please copy me via email if you respond.
  1473.  
  1474. Thanks!
  1475.  
  1476. -Tom Morrow
  1477.  tmorrow@us.oracle.com
  1478.  
  1479.  
  1480.  
  1481.  
  1482.  
  1483.  
  1484. +++++++++++++++++++++++++++
  1485.  
  1486. >From fesh@applelink.apple.com (TheBug)
  1487. Date: 29 Jul 1995 13:30:30 GMT
  1488. Organization: privat
  1489.  
  1490. In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
  1491. tmorrow@us.oracle.com (tmorrow) wrote:
  1492.  
  1493. > We are in the process of porting some batch programs over to the
  1494. > Macintosh from UNIX, and realizing that the Mac has no command line
  1495. > argument interface for invoking executables.
  1496. > This is a major bummer, and are curious about what other people have
  1497. > done in this type of situation.
  1498. > We basically have one program which sequentially spawns processes to do
  1499. > various batch type tasks, communicating important paramters to the
  1500. > child processes through the command line.  We have thought of using
  1501. > files to communicate the same information that we communicated on the
  1502. > command line in UNIX.  The files would be the documents in Mac's
  1503. > document-centric interface; invoking (opening) a file of command line
  1504. > arguments would be equivalent to invoking an application with those
  1505. > command line arguments on UNIX.  Another idea would be apple events,
  1506. > but that would probably require even more "nativising" which we don't
  1507. > want to do if we don't have to.
  1508. > Is there some kind of library or some other simple solution that won't
  1509. > require as much native coding as using files of arguments or passing
  1510. > the arguments through apple events?  Ideally there would be a way to
  1511. > keep the argc, argv processing code just the way it is on UNIX.
  1512. > It seems like a glaring deficiency that the Mac has no way of passing
  1513. > paramters to an application upon startup, but I guess that is due to
  1514. > its document-centric design, eh?
  1515.  
  1516. Hope you intend to use this only in-house and have no intention to sell
  1517. it. If you try to sell such a solution to the Mac community I would rather
  1518. suggest to stop right now and not waste your energy. Any magazine review
  1519. of such a program would be a bad bashing up.
  1520.  
  1521. If this program is for end user sales you will have to go the full way and
  1522. make it a real Mac application, otherwise you will get buried in the
  1523. market. Mac users are kind of allergic to "cheap ports".
  1524.  
  1525. If this is just for in-house use you should get yourself MPW from Apple.
  1526. This is basically a development environment but it offers you standard
  1527. command line interfacing with argc, argv, output redirection and all the
  1528. stuff.
  1529.  
  1530. +++++++++++++++++++++++++++
  1531.  
  1532. >From Richard Wesley <hawkfish@punchdeck.com>
  1533. Date: 29 Jul 1995 16:02:37 GMT
  1534. Organization: Punch Deck Consulting
  1535.  
  1536. tmorrow@us.oracle.com (tmorrow) wrote:
  1537. >
  1538. >We are in the process of porting some batch programs over to the
  1539. >Macintosh from UNIX, and realizing that the Mac has no command line
  1540. >argument interface for invoking executables.
  1541. >
  1542. >This is a major bummer, and are curious about what other people have
  1543. >done in this type of situation.
  1544. >
  1545. >We basically have one program which sequentially spawns processes to do
  1546. >various batch type tasks, communicating important paramters to the
  1547. >child processes through the command line.  We have thought of using
  1548. >files to communicate the same information that we communicated on the
  1549. >command line in UNIX.  The files would be the documents in Mac's
  1550. >document-centric interface; invoking (opening) a file of command line
  1551. >arguments would be equivalent to invoking an application with those
  1552. >command line arguments on UNIX.  Another idea would be apple events,
  1553. >but that would probably require even more "nativising" which we don't
  1554. >want to do if we don't have to.
  1555. >
  1556. >Is there some kind of library or some other simple solution that won't
  1557. >require as much native coding as using files of arguments or passing
  1558. >the arguments through apple events?  Ideally there would be a way to
  1559. >keep the argc, argv processing code just the way it is on UNIX.
  1560. >
  1561. >It seems like a glaring deficiency that the Mac has no way of passing
  1562. >paramters to an application upon startup, but I guess that is due to
  1563. >its document-centric design, eh?
  1564.  
  1565. There _is_ a way to do this - AppleEvents.  All you have to do
  1566. is define your own AE that passes a command line.  Then you can write one 
  1567. bottleneck routine that takes a process name and a command line and 
  1568. launches the process with the given AE.  Each process then just needs a
  1569. shell that recieves the AE and breaks it up for your "main".
  1570.  
  1571. - rmgw
  1572.  
  1573. http://www.punchdeck.com/hawkfish/PunchDeck.html
  1574.  
  1575. - --------------------------------------------------------------------------
  1576. Richard Wesley  hawkfish@punchdeck.com | "'Hand it round first, and cut it
  1577. Punch Deck Consulting pnchdeck@aol.com |  afterwards.'" - Lewis Carroll,
  1578.      Macintosh Software Development    |    "Through the Looking Glass"
  1579. - --------------------------------------------------------------------------
  1580.  
  1581.  
  1582.  
  1583. +++++++++++++++++++++++++++
  1584.  
  1585. >From 3gl21@qlink.queensu.ca (Gregory Lo)
  1586. Date: Sat, 29 Jul 1995 22:13:25 -0400
  1587. Organization: Queen's University
  1588.  
  1589. In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
  1590. tmorrow@us.oracle.com (tmorrow) wrote:
  1591.  
  1592. > We are in the process of porting some batch programs over to the
  1593. > Macintosh from UNIX, and realizing that the Mac has no command line
  1594. > argument interface for invoking executables.
  1595.  
  1596. > We basically have one program which sequentially spawns processes to do
  1597. > various batch type tasks, communicating important paramters to the
  1598. > child processes through the command line.  We have thought of using
  1599. > files to communicate the same information that we communicated on the
  1600. > command line in UNIX.  The files would be the documents in Mac's
  1601. > document-centric interface; invoking (opening) a file of command line
  1602. > arguments would be equivalent to invoking an application with those
  1603. > command line arguments on UNIX.
  1604.  
  1605. Don't do this.  No Mac end-user would ever want to bother with this hassle.
  1606.  
  1607. > Another idea would be apple events,
  1608. > but that would probably require even more "nativising" which we don't
  1609. > want to do if we don't have to.
  1610.  
  1611. This is the way to go.  (You would recieve Apple Events, anyway)
  1612. Apple Events are _the_ medium of interapplication communication in MacOS. 
  1613. Their use is standard and necessary for later versions of MacOS.
  1614.  
  1615. > Is there some kind of library or some other simple solution that won't
  1616. > require as much native coding as using files of arguments or passing
  1617. > the arguments through apple events?  Ideally there would be a way to
  1618. > keep the argc, argv processing code just the way it is on UNIX.
  1619.  
  1620. Most commercial compilers will include console interfaces and libraries to
  1621. ease porting of programs from other platforms.  Or, you could use MPW, but
  1622. then your program could only be used from within the MPW environment.
  1623.  
  1624. > It seems like a glaring deficiency that the Mac has no way of passing
  1625. > paramters to an application upon startup, but I guess that is due to
  1626. > its document-centric design, eh?
  1627.  
  1628. Actually, you _do_ get information passed to your application upon startup
  1629. anyway via one of three of the four _required_ Apple Events:  "Open
  1630. Application", "Open Document(s)", "Print Document(s)".
  1631. Creating files and then opening them as a means of passing parameters ends
  1632. up creating and sending "Open Document" Apple Events, anyway.  If your
  1633. application were properly written for MacOS, it should be no trouble to
  1634. extend to the use of other Apple Events.  I'm sure there are libraries and
  1635. frameworks to make this incredibly easy for you.
  1636.  
  1637. A third alternative is to make use of threads.  Threads operate similiarly
  1638. on almost all platforms and OS' that support them.  Your UN*X probably
  1639. supports the use of threads.  Beware, though, that pre-emptive threads in
  1640. MacOS are now only supported on 68K machines, using System 7.5 or later,
  1641. or using System 7.1 with the Thread Manager extension. 
  1642.  
  1643. GLo
  1644.  
  1645. ps. I've never really considered the Mac as a document-centric interface. 
  1646. I just don't see how it would differ from other OS' (like UN*X) in that
  1647. respect.  OLE and OpenDoc, I would consider document-centric interfaces.
  1648.  
  1649. - ---------------------------------------------------------
  1650. Gregory Lo  GLo ?:^(>      <mailto:3gl21@qlink.queensu.ca>
  1651.  
  1652. +++++++++++++++++++++++++++
  1653.  
  1654. >From ckt@best.com (Chris Thomas)
  1655. Date: Sat, 29 Jul 1995 20:36:29 -0800
  1656. Organization: Echo Software
  1657.  
  1658. In article <fesh-2907951530280001@async107.zrz.tu-berlin.de>,
  1659. fesh@applelink.apple.com (TheBug) wrote:
  1660.  
  1661. > In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
  1662. > tmorrow@us.oracle.com (tmorrow) wrote:
  1663. > > We are in the process of porting some batch programs over to the
  1664. > > Macintosh from UNIX, and realizing that the Mac has no command line
  1665. > > argument interface for invoking executables.
  1666. > > 
  1667. > > This is a major bummer, and are curious about what other people have
  1668. > > done in this type of situation.
  1669. > > 
  1670. > > We basically have one program which sequentially spawns processes to do
  1671. > > various batch type tasks, communicating important paramters to the
  1672. > > child processes through the command line.  We have thought of using
  1673. > > files to communicate the same information that we communicated on the
  1674. > > command line in UNIX.  The files would be the documents in Mac's
  1675. > > document-centric interface; invoking (opening) a file of command line
  1676. > > arguments would be equivalent to invoking an application with those
  1677. > > command line arguments on UNIX.  Another idea would be apple events,
  1678. > > but that would probably require even more "nativising" which we don't
  1679. > > want to do if we don't have to.
  1680. > > 
  1681. > > Is there some kind of library or some other simple solution that won't
  1682. > > require as much native coding as using files of arguments or passing
  1683. > > the arguments through apple events?  Ideally there would be a way to
  1684. > > keep the argc, argv processing code just the way it is on UNIX.
  1685. > > 
  1686. > > It seems like a glaring deficiency that the Mac has no way of passing
  1687. > > paramters to an application upon startup, but I guess that is due to
  1688. > > its document-centric design, eh?
  1689. > Hope you intend to use this only in-house and have no intention to sell
  1690. > it. If you try to sell such a solution to the Mac community I would rather
  1691. > suggest to stop right now and not waste your energy. Any magazine review
  1692. > of such a program would be a bad bashing up.
  1693. > If this program is for end user sales you will have to go the full way and
  1694. > make it a real Mac application, otherwise you will get buried in the
  1695. > market. Mac users are kind of allergic to "cheap ports".
  1696. > If this is just for in-house use you should get yourself MPW from Apple.
  1697. > This is basically a development environment but it offers you standard
  1698. > command line interfacing with argc, argv, output redirection and all the
  1699. > stuff.
  1700.  
  1701. Also, don't forget that the AppleEvent manager *is* the Mac version
  1702. of command-line arguments- difference being that AppleEvents are
  1703. highly typed.  You'll have to nativize if you expect to reap the
  1704. benefits of the Macintosh architecture.
  1705.  
  1706. -- 
  1707. Chris Thomas, ckt@best.com
  1708.  
  1709. +++++++++++++++++++++++++++
  1710.  
  1711. >From jthill@netcom.com (Jim Hill)
  1712. Date: Sun, 30 Jul 1995 06:39:45 GMT
  1713. Organization: biological <-- hey! a one-word oxymoron!
  1714.  
  1715. In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com>,
  1716. tmorrow@us.oracle.com (tmorrow) wrote:
  1717.  
  1718. >We are in the process of porting some batch programs over to the
  1719. >Macintosh from UNIX, and realizing that the Mac has no command line
  1720. >argument interface for invoking executables.
  1721.  
  1722. I think Greg Lo hit the nail on the head; this is just another take on the
  1723. same idea.  
  1724.  
  1725. There are lots of ways to do what you want, but as you've noticed they're
  1726. all different from what UNIX does, and (csmp.misc guys, come on, let's
  1727. admit this) it's a pain in the butt when you're porting.  But as Greg
  1728. pointed out, if you don't do the work you don't have a Mac program, and if
  1729. Mac users see it they'll leave you on the shelf.
  1730.  
  1731. When launching programs, you can specify an apple event to feed them on
  1732. startup.  It can be anything you want.  You can build it yourself, get it
  1733. from a document, whatever.  You wrote the code on both ends, so if you're
  1734. really into not porting you can just make up a command-line apple event;
  1735. it'll be the first thing your code sees and if I recall the Oracle coding
  1736. guidelines correctly you've got an s0-prefix main on every one of them
  1737. anyway.
  1738.  
  1739. Given time, I'd go farther and just bypass out the command-line processing
  1740. completely, using appleevents instead:  run transactions that have the
  1741. parameters already digested and a list of docs (or whatever) to run them
  1742. on, and have both the unix cmdline parsing and mac appleevent breakout
  1743. drive exactly the same processing code.
  1744.  
  1745.  
  1746. Just riffing,
  1747. Jim
  1748.  
  1749. obStuffIApologizeForNotDeleting:
  1750. At any rate, IM-Processes has lots of good stuff along these lines.  Try
  1751. scripting a UNIX process sometime :-) -- "expect" is a gross, limited
  1752. hack.  I guess that is due to UNIX's keyboard-centric design, eh?  ;-)
  1753. -- 
  1754. Jim Hill              Contents public domain and worth $.02 more than you paid.
  1755. jthill@netcom.com     PGPrint: 6B 85 76 D1 EF BA 2C 78  12 25 8A 5A BF F3 37 7E
  1756.  
  1757. +++++++++++++++++++++++++++
  1758.  
  1759. >From Manuel Veloso <veloso@RT66.com>
  1760. Date: 1 Aug 1995 14:58:07 GMT
  1761. Organization: Ibex Productions
  1762.  
  1763. In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com> tmorrow,
  1764. tmorrow@us.oracle.com writes:
  1765. >Is there some kind of library or some other simple solution that won't
  1766. >require as much native coding as using files of arguments or passing
  1767. >the arguments through apple events?  Ideally there would be a way to
  1768. >keep the argc, argv processing code just the way it is on UNIX.
  1769. >
  1770.  
  1771. Well, if it's not going to be public, how about using MPW?
  1772. You guys probably have a copy in-house somewhere.
  1773.  
  1774. The only downsides are that you can't launch a tool from another
  1775. tool, and everything's linear (ie: tool/script/tool/tool).
  1776.  
  1777. Another option is to applescript it, with each batch program being
  1778. an OSAXen and an applescript being the makefile/driver equivalent.
  1779. Putting a shell around your programs that extracts params from
  1780. the AppleEvents, transforms them into argv/argc, and returns values
  1781. shouldn't be that hard.
  1782.  
  1783. Manuel
  1784.  
  1785. +++++++++++++++++++++++++++
  1786.  
  1787. >From Manuel Veloso <veloso@RT66.com>
  1788. Date: 1 Aug 1995 14:58:07 GMT
  1789. Organization: Ibex Productions
  1790.  
  1791. In article <3vbuqe$cpc@inet-nntp-gw-1.us.oracle.com> tmorrow,
  1792. tmorrow@us.oracle.com writes:
  1793. >Is there some kind of library or some other simple solution that won't
  1794. >require as much native coding as using files of arguments or passing
  1795. >the arguments through apple events?  Ideally there would be a way to
  1796. >keep the argc, argv processing code just the way it is on UNIX.
  1797. >
  1798.  
  1799. Well, if it's not going to be public, how about using MPW?
  1800. You guys probably have a copy in-house somewhere.
  1801.  
  1802. The only downsides are that you can't launch a tool from another
  1803. tool, and everything's linear (ie: tool/script/tool/tool).
  1804.  
  1805. Another option is to applescript it, with each batch program being
  1806. an OSAXen and an applescript being the makefile/driver equivalent.
  1807. Putting a shell around your programs that extracts params from
  1808. the AppleEvents, transforms them into argv/argc, and returns values
  1809. shouldn't be that hard.
  1810.  
  1811. Manuel
  1812.  
  1813. ---------------------------
  1814.  
  1815. End of C.S.M.P. Digest
  1816. **********************
  1817.